from typing import Literal, TypeAlias, TYPE_CHECKING
from puzzle.mathF import get_center

if TYPE_CHECKING:
    from puzzle.mathF import Vec2

TileType_t : TypeAlias = Literal["month", "day", "weekday", "blank"]

class Tile:
    def __init__(self, type: TileType_t, label: str) -> None:
        self.type: TileType_t = type
        self.label: str = label
        
        self.is_blank: bool = self.type == "blank"

    def __str__(self) -> str:
        return f"Tile({self.label})"

    def __repr__(self) -> str:
        return self.__str__()


class TileDesc:
    def __init__(
        self,
        
        tile: Tile,
        
        # Board-relative
        row: int,
        col: int,
        
        # Window-relative
        v_alone: "Vec2",
        v_left: "Vec2",
        v_right: "Vec2",
    ) -> None:
        self.tile:    Tile   = tile
        self.row:     int    = row
        self.col:     int    = col
        self.v_alone: "Vec2" = v_alone
        self.v_left:  "Vec2" = v_left
        self.v_right: "Vec2" = v_right
        
        self.vertices: tuple["Vec2", "Vec2", "Vec2"] = (self.v_alone, self.v_left, self.v_right)
        self.center: "Vec2" = get_center(self.vertices)

        self.is_facing_up: bool = col % 2 == 0
        if not 0 <= row <= 2: self.is_facing_up = not self.is_facing_up
        self.is_facing_down: bool = not self.is_facing_up
        
        self.special_x_index = int(self.center.x * 2) + 5

    def __str__(self) -> str:
        return f"TileDesc({self.tile}, {self.row}, {self.col})"

    def __repr__(self) -> str:
        return self.__str__()


class TileSet(set[TileDesc]):
    def __init__(self, *td: TileDesc) -> None:
        super().__init__(td)
    
    def __str__(self) -> str:
        tiles = [str(td.tile) for td in self]
        return f"TileSet({", ".join(tiles)})"
    
    def __repr__(self) -> str:
        return self.__str__()